using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Publicuse.Entity;
using Publicuse.Entity.other;

namespace Publicuse.Util.Jwt
{
  public class CustomHSJWTService : ICustomJWTService
  {
    #region Option注入
    private readonly JWTTokenOptions _JWTTokenOptions;

    public CustomHSJWTService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
    {
      this._JWTTokenOptions = jwtTokenOptions.CurrentValue;
    }
    #endregion

    /// <summary>
    /// 获取token
    /// </summary>
    /// <param name="user"></param>
    /// <param name="authtoken"></param>
    /// <param name="SysTimeOut"></param>
    /// <param name="msg"></param>
    /// <param name="jwtToken"></param>
    /// <returns></returns>
    public string GetToken(
      User user,
      string authtoken,
      int SysTimeOut,
      out string msg,
      out JwtToken jwtToken
    )
    {
      msg = string.Empty;
      jwtToken = null;
      string result = string.Empty;
      try
      {
        jwtToken = new JwtToken()
        {
          Id = user.Id.ToString(),
          uName = user.uName ?? "",
          uCode = user.uCode ?? "",
          rId = user.rId ?? "",
          //rsName = user.rsName ?? "",
          rName = user.rName ?? "",
          appid = user.appid ?? "",
          uEmail = user.uEmail ?? "",
          uMobile = user.uMobile ?? "",
          uPhone = user.uPhone ?? "",
          cTime = DateTime.Now.AddMinutes(SysTimeOut).ToString("yyyy-MM-dd HH:mm:ss"),
          iss = "https://xcaq.gzticc.cn:19105",
          aud = "https://xcaq.gzticc.cn:19105",
          exp = TimestampUtil.GetTimeStamp(),
          authtoken = authtoken,
          uploadyhead = user.uploadyhead
        };
        #region 有效载荷，大家可以自己写，爱写多少写多少；尽量避免敏感信息
        var claims = new[]
        {
          new Claim("Id", user.Id.ToString()),
          new Claim("rId", user.rId ?? ""),
          //new Claim("rsName",user.rsName??""),
          new Claim("rNameb", user.rName ?? ""),
          new Claim("uName", user.uName ?? ""),
          new Claim("uCode", user.uCode ?? ""),
          new Claim("appid", user.appid ?? ""),
          //new Claim("uEmail",user.uEmail??""),
          //new Claim("uMobile",user.uMobile??""),
          //new Claim("uPhone",user.uPhone??""),
          //new Claim("sName",user.sName??""),
          new Claim("SysTimeOut", SysTimeOut.ToString()),
          new Claim("cTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
          new Claim("authtoken", authtoken ?? ""),
          new Claim("uploadyhead", user.uploadyhead ?? ""),
        };

        //需要加密：需要加密key:
        //Nuget引入：Microsoft.IdentityModel.Tokens
        SymmetricSecurityKey key = new SymmetricSecurityKey(
          Encoding.UTF8.GetBytes("xKKmIONl3bXcNxkajAsuvg==")
        );

        SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        //Nuget引入：System.IdentityModel.Tokens.Jwt
        //JwtSecurityToken token = new JwtSecurityToken(
        // issuer: "https://sjbs.gzticc.cn:8012",
        // audience: "https://sjbs.gzticc.cn:8012",
        // claims: claims,
        // expires: DateTime.Now.AddMinutes(SysTimeOut),//设置超时有效期
        // signingCredentials: creds);

        JwtSecurityToken token = new JwtSecurityToken(
          issuer: "ticc",
          audience: "ticc",
          claims: claims,
          expires: DateTime.Now.AddMinutes(SysTimeOut), //设置超时有效期
          signingCredentials: creds
        );

        result = new JwtSecurityTokenHandler().WriteToken(token);
        #endregion
      }
      catch (Exception ex)
      {
        msg = ex.Message;
      }
      return result;
    }

    /// <summary>
    /// 获取token
    /// </summary>
    /// <param name="user"></param>
    /// <param name="authtoken"></param>
    /// <param name="SysTimeOut"></param>
    /// <param name="msg"></param>
    /// <param name="jwtToken"></param>
    /// <returns></returns>
    public string GetTokenpermission(
       User user,
       string authtoken,
       int SysTimeOut,
       out string msg,
       out JwtToken jwtToken
     )
    {
      msg = string.Empty;
      jwtToken = null;
      string result = string.Empty;
      try
      {
        jwtToken = new JwtToken()
        {
          Id = user.Id.ToString(),
          cTime = DateTime.Now.AddMinutes(SysTimeOut).ToString("yyyy-MM-dd HH:mm:ss"),
          iss = "https://xcaq.gzticc.cn:19105",
          aud = "https://xcaq.gzticc.cn:19105",
          exp = TimestampUtil.GetTimeStamp(),
          authtoken = authtoken,
          uploadyhead = user.uploadyhead
        };
        #region 有效载荷，大家可以自己写，爱写多少写多少；尽量避免敏感信息
        var claims = new[]
        {
          new Claim("Id", user.Id.ToString()),
          new Claim("SysTimeOut", SysTimeOut.ToString()),
          new Claim("cTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
          new Claim("authtoken", authtoken ?? ""),
          new Claim("uploadyhead", user.uploadyhead ?? ""),
        };

        //需要加密：需要加密key:
        //Nuget引入：Microsoft.IdentityModel.Tokens
        SymmetricSecurityKey key = new SymmetricSecurityKey(
          Encoding.UTF8.GetBytes("xKKmIONl3bXcNxkajAsuvg==")
        );

        SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        //Nuget引入：System.IdentityModel.Tokens.Jwt
        //JwtSecurityToken token = new JwtSecurityToken(
        // issuer: "https://sjbs.gzticc.cn:8012",
        // audience: "https://sjbs.gzticc.cn:8012",
        // claims: claims,
        // expires: DateTime.Now.AddMinutes(SysTimeOut),//设置超时有效期
        // signingCredentials: creds);

        JwtSecurityToken token = new JwtSecurityToken(
          issuer: "ticc",
          audience: "ticc",
          claims: claims,
          expires: DateTime.Now.AddMinutes(SysTimeOut), //设置超时有效期
          signingCredentials: creds
        );

        result = new JwtSecurityTokenHandler().WriteToken(token);
        #endregion
      }
      catch (Exception ex)
      {
        msg = ex.Message;
      }
      return result;
    }
  }
}
